﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using System.Threading;
using VIBlend.Utilities;

namespace Monopoly
{
	public partial class Form1 : Form
	{
		private static List<Village> lstVillages;
		private List<Player> players;
		private Setup setup;
		private Card card;
		private int freeParking;

		public delegate void OnTurnFinished(Player playerFinished);
		internal event OnTurnFinished onTurnFinished;

		private delegate void Step();
		private Player currentPlayer;

		// locations on the board
		private int[] pbVillages = new int[] { 1, 3, 5, 6, 8, 9, 11, 12, 13, 14, 15, 16, 18, 19, 21, 23, 24, 25, 26, 27, 28, 29, 31, 32, 34, 35, 37, 39 };
		private int[] pbAlgemeenFonds = new int[] { 2, 17, 33 };
		private int[] pbKans = new int[] { 7, 22, 36 };
		private int[] pbBelasting = new int[] { 4, 38 };

		public Form1(List<Player> t_players)
		{
			loadVillages();

			players = t_players;
            card = new Card();

            onTurnFinished += new OnTurnFinished(turnFinished);
            InitializeComponent();

            initPlayerPanel();



            btnEndTurn.Enabled = false;
			begin();
		}

        private void initPlayerPanel()
        {
            Player p;

            // add players to navpanel
            for (int i = 0; i < players.Count; i++)
            {
                p = players[i];

                npPlayers.Items.Add(new VIBlend.WinForms.Controls.vNavPaneItem());
                npPlayers.Items[i].HeaderText = p.Name;

                npPlayers.Items[i].HeaderControl.BackColor = Color.Red;

                VIBlend.Utilities.ControlTheme theme = npPlayers.Theme;

                //  theme.StyleDisabled.FillStyle = new VIBlend.Utilities.FillStyleSolid(Color.Red);
                theme.StyleNormal.FillStyle = createGradient(p.Color); // default
                //       theme.StyleHighlight.FillStyle = new VIBlend.Utilities.FillStyleSolid(Color.Red);
                theme.StylePressed.FillStyle = createGradient(p.Color); // actief
                //     theme.StyleDisabledPressed.FillStyle = new VIBlend.Utilities.FillStyleSolid(Color.Red);
                npPlayers.Items[i].HeaderTheme = theme;

                npPlayers.Refresh();

               

                System.Windows.Forms.Control.ControlCollection controlCollection = npPlayers.Items[i].ItemPanel.Controls;

                // money 1
                PictureBox pb = new PictureBox();
                pb.BackgroundImage = global::Monopoly.Properties.Resources.briefgeld_een;
                pb.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch;
                pb.Size = new System.Drawing.Size(65, 28);
                pb.Location = new Point(60, 10);
                controlCollection.Add(pb);
                
                Label lblX = new Label();
                lblX.Text = "x";
                lblX.Location = new Point(42, 17);
                controlCollection.Add(lblX);

                Label lblCount = new Label();
                lblCount.Location = new Point(5, 17);
                lblCount.DataBindings.Add("Text", p, "One");
                controlCollection.Add(lblCount);

                // money 2
                pb = new PictureBox();
                pb.BackgroundImage = global::Monopoly.Properties.Resources.briefgeld_vijf;
                pb.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch;
                pb.Size = new System.Drawing.Size(65, 28);
                pb.Location = new Point(60, 45);
                controlCollection.Add(pb);

                lblX = new Label();
                lblX.Text = "x";
                lblX.Location = new Point(42, 52);
                controlCollection.Add(lblX);

                lblCount = new Label();
                lblCount.Location = new Point(5, 52);
                lblCount.DataBindings.Add("Text", p, "Five");
                controlCollection.Add(lblCount);

                // money 3
                pb = new PictureBox();
                pb.BackgroundImage = global::Monopoly.Properties.Resources.briefgeld_tien;
                pb.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch;
                pb.Size = new System.Drawing.Size(65, 28);
                pb.Location = new Point(60, 80);
                controlCollection.Add(pb);

                lblX = new Label();
                lblX.Text = "x";
                lblX.Location = new Point(42, 87);
                controlCollection.Add(lblX);

                lblCount = new Label();
                lblCount.Location = new Point(5, 87);
                lblCount.DataBindings.Add("Text", p, "Ten");
                controlCollection.Add(lblCount);

                // money 4
                pb = new PictureBox();
                pb.BackgroundImage = global::Monopoly.Properties.Resources.briefgeld_twintig;
                pb.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch;
                pb.Size = new System.Drawing.Size(65, 28);
                pb.Location = new Point(60, 115);
                npPlayers.Items[i].ItemPanel.Controls.Add(pb);

                lblX = new Label();
                lblX.Text = "x";
                lblX.Location = new Point(42, 122);
                controlCollection.Add(lblX);

                lblCount = new Label();
                lblCount.Location = new Point(5, 122);
                lblCount.DataBindings.Add("Text", p, "Twenty");
                controlCollection.Add(lblCount);

                // money 5
                pb = new PictureBox();
                pb.BackgroundImage = global::Monopoly.Properties.Resources.briefgeld_vijftig;
                pb.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch;
                pb.Size = new System.Drawing.Size(65, 28);
                pb.Location = new Point(250, 10);
                npPlayers.Items[i].ItemPanel.Controls.Add(pb);

                lblX = new Label();
                lblX.Text = "x";
                lblX.Location = new Point(232, 17);
                controlCollection.Add(lblX);

                lblCount = new Label();
                lblCount.Location = new Point(205, 17);
                lblCount.DataBindings.Add("Text", p, "Fifty");
                controlCollection.Add(lblCount);

                // money 6
                pb = new PictureBox();
                pb.BackgroundImage = global::Monopoly.Properties.Resources.briefgeld_honderd;
                pb.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch;
                pb.Size = new System.Drawing.Size(65, 28);
                pb.Location = new Point(250, 45);
                npPlayers.Items[i].ItemPanel.Controls.Add(pb);

                lblX = new Label();
                lblX.Text = "x";
                lblX.Location = new Point(232, 52);
                controlCollection.Add(lblX);

                lblCount = new Label();
                lblCount.Location = new Point(205, 52);
                lblCount.DataBindings.Add("Text", p, "Hunderd");
                controlCollection.Add(lblCount);

                // money 7
                pb = new PictureBox();
                pb.BackgroundImage = global::Monopoly.Properties.Resources.briefgeld_vijfhonderd;
                pb.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch;
                pb.Size = new System.Drawing.Size(65, 28);
                pb.Location = new Point(250, 80);
                npPlayers.Items[i].ItemPanel.Controls.Add(pb);

                lblX = new Label();
                lblX.Text = "x";
                lblX.Location = new Point(232, 87);
                controlCollection.Add(lblX);

                lblCount = new Label();
                lblCount.Location = new Point(205, 87);
                lblCount.DataBindings.Add("Text", p, "Fivehunderd");
                controlCollection.Add(lblCount);
            }
        }

        private FillStyle createGradient(Color color)
        {
            int r, g, b;

            r = color.R + (color.R + 100 > 255 ? -100 : 100);
            g = color.G + (color.G + 100 > 255 ? -100 : 100);
            b = color.B + (color.B + 100 > 255 ? -100 : 100);

            return new FillStyleGradient(color, Color.WhiteSmoke, System.Drawing.Drawing2D.LinearGradientMode.Vertical);
        }

		private void begin()
		{
			foreach (Player p in players)
			{
				if (p.Turn == true)
				{
					currentPlayer = p;
				}
			}
			PlayerStatistics();
		}

		void turnFinished(Player playerFinished)
		{
			playerFinished.Turn = false;
			if (players.IndexOf(playerFinished) + 1 == players.Count())
				currentPlayer = players[0];
			else
				currentPlayer = players[players.IndexOf(playerFinished) + 1];
			currentPlayer.Turn = true;

			PlayerStatistics();

			btnEndTurn.Enabled = false;
			btnThrowDice.Enabled = currentPlayer.JailDiceThrows < 3;
			if (currentPlayer.IsInJail)
			{
				btpay.Visible = true;
				lbljail.Visible = true;
			}

		}

		private void pictureBox1_Click(object sender, EventArgs e)
		{

		}

		public static List<Village> loadVillages()
		{
			lstVillages = new List<Village>();
			XmlDocument doc = new XmlDocument();
			doc.LoadXml(Properties.Resources.villages);
			XmlNode villagesNode = doc.FirstChild;

			foreach (XmlNode villageNode in villagesNode.ChildNodes)
			{
				lstVillages.Add(new Village(villageNode["Name"].InnerText, int.Parse(villageNode["Price"].InnerText), int.Parse(villageNode["HousePrice"].InnerText), int.Parse(villageNode["HotelPrice"].InnerText)));
			}
			return lstVillages;
		}

		private void village_Click(object sender, EventArgs e)
		{
			PictureBox pictureBox = (PictureBox)sender;
			int villageNr = int.Parse(pictureBox.Name.Substring(7));
			Village clickedVillage = lstVillages[villageNr - 1];
			new VillageCard(clickedVillage);
		}

		protected override void OnPaint(PaintEventArgs paintEvnt)
		{
            Control control;
            Graphics graphicsObj;
            Pen pen;
			foreach (Player p in players)
			{
                control = this.pnlBord.Controls["pb" + p.Position];
                graphicsObj = control.CreateGraphics();
                pen = new Pen(p.Color);
                graphicsObj.FillEllipse(pen.Brush, 2, 2, 25, 25);
			}
		}

		protected void PlayerStatistics()
		{
			lblturnoutput.Text = currentPlayer.Name;
			lblone.Text = currentPlayer.One.ToString();
			lblfive.Text = currentPlayer.Five.ToString();
			lblten.Text = currentPlayer.Ten.ToString();
			lbltwenty.Text = currentPlayer.Twenty.ToString();
			lblfifty.Text = currentPlayer.Fifty.ToString();
			lblhunderd.Text = currentPlayer.Hunderd.ToString();
			lblfivehunderd.Text = currentPlayer.Fivehunderd.ToString();
			lbltotalcash.Text = currentPlayer.TotalMoney().ToString();
		}

		private void btnThrowDice_Click(object sender, EventArgs e)
		{
			int dice1, dice2;

			// not in jail
			if (!currentPlayer.IsInJail)
			{
				// enable / disable buttons
				btnEndTurn.Enabled = !currentPlayer.ThrowDice(out dice1, out dice2);
				btnThrowDice.Enabled = !btnEndTurn.Enabled;

				// set images
				pbDice1.ImageLocation = "images/dice" + dice1 + ".png";
				pbDice2.ImageLocation = "images/dice" + dice2 + ".png";

				// start steps
				Thread t = new Thread(new ParameterizedThreadStart(movePlayer));
				t.Start(dice1 + dice2);
			}
			else
			{

				if (currentPlayer.JailDiceThrows < 3)
				{
					if (currentPlayer.ThrowDice(out dice1, out dice2))
					{
						currentPlayer.IsInJail = false;
						currentPlayer.JailDiceThrows = 0;
					}
					currentPlayer.JailDiceThrows++;
				}
				else
				{
					if (MessageBox.Show("Je hebt al 3 keer gegooid, je moet nu 50 euro betalen", "Teveel gegooid", MessageBoxButtons.OKCancel) == DialogResult.OK)
					{
						currentPlayer.pay(50);
						currentPlayer.IsInJail = false;
						currentPlayer.JailDiceThrows = 0;
					}
				}
			}
		}


		private void movePlayer(object obj)
		{
			int steps = (int)obj;

			// remove current position
			Control control = this.pnlBord.Controls["pb" + currentPlayer.Position];
			if (control.InvokeRequired)
			{
				control.Invoke(new MethodInvoker(control.Invalidate));
				control.Invoke(new MethodInvoker(control.Refresh));
			}
			else
			{
				control.Invalidate();
				control.Refresh();
			}

			// draw steps
            Graphics graphicsObj;
            Pen pen;
			for (int i = 0; i < steps; i++)
			{
				control = this.pnlBord.Controls["pb" + ++currentPlayer.Position];
				graphicsObj = control.CreateGraphics();
				pen = new Pen(currentPlayer.Color);

                // nr of players on field
                // players.Where(p => p.Position == currentPlayer.Position).Count()
                graphicsObj.FillEllipse(pen.Brush, 2, 2, 25, 25);
				System.Threading.Thread.Sleep(400);

				if (i < steps - 1)
				{
					if (control.InvokeRequired)
					{
						control.Invoke(new MethodInvoker(control.Invalidate));
						control.Invoke(new MethodInvoker(control.Refresh));
					}
					else
					{
						control.Invalidate();
						control.Refresh();
					}
				}
			}

			canBuyVillage(pbVillages.Contains(currentPlayer.Position));

			if (pbAlgemeenFonds.Contains(currentPlayer.Position))
				algemeenFonds();
			else if (pbKans.Contains(currentPlayer.Position))
				kans();
			else if (pbBelasting.Contains(currentPlayer.Position))
				belasting();
			else if (currentPlayer.Position == 20)
				vrijParkeren();
			else if (currentPlayer.Position == 30)
				gevangenis();
		}

		private void gevangenis()
		{
			currentPlayer.Position = 10;
			currentPlayer.IsInJail = true;
		}

		private void vrijParkeren()
		{
			currentPlayer.earn_money(freeParking);
			freeParking = 0;
		}

		private void belasting()
		{
			if (currentPlayer.Position == 4)
			{
				currentPlayer.pay(200);
				freeParking += 200;
			}
			else if (currentPlayer.Position == 38)
			{
				currentPlayer.pay(100);
				freeParking += 100;
			}
		}

		private void kans()
		{
			if (card.show(Card.CardType.kans))
				currentPlayer.FreeJailKans = true;
		}

		private void algemeenFonds()
		{
			if (card.show(Card.CardType.algemeenFonds))
				currentPlayer.FreeJailAlgemeenFonds = true;
		}


		delegate void canBuyVillageCallback(bool p);

		private void canBuyVillage(bool p)
		{
			if (this.btnBuyVillage.InvokeRequired)
			{
				canBuyVillageCallback d = new canBuyVillageCallback(canBuyVillage);
				this.Invoke(d, new object[] { p });
			}
			else
			{
				this.btnBuyVillage.Enabled = p;
			}
		}


		private void btnEndTurn_Click(object sender, EventArgs e)
		{
			if (onTurnFinished != null)
				onTurnFinished.Invoke(currentPlayer);
		}

		private void btnBuyVillage_Click(object sender, EventArgs e)
		{

		}

		private void btpay_Click(object sender, EventArgs e)
		{
			currentPlayer.pay(50);
			currentPlayer.IsInJail = false;
			currentPlayer.JailDiceThrows = 0;
		}

        private void btfreejail_Click(object sender, EventArgs e)
        {
            if (currentPlayer.FreeJailAlgemeenFonds)
            {
                currentPlayer.IsInJail = false;
                currentPlayer.JailDiceThrows = 0;
                currentPlayer.FreeJailAlgemeenFonds = false;
                btnThrowDice.Enabled = currentPlayer.JailDiceThrows < 3;

            }
            else if (currentPlayer.FreeJailKans)
            {
                currentPlayer.IsInJail = false;
                currentPlayer.JailDiceThrows = 0;
                currentPlayer.FreeJailKans = false;
                btnThrowDice.Enabled = currentPlayer.JailDiceThrows < 3;
            }
        }

        private void pnlBord_Scroll(object sender, ScrollEventArgs e)
        {
            this.Invalidate();
        }

    }
}
